package com.sojson.util;

import java.security.CodeSource;
import java.security.ProtectionDomain;

/**
 * 堆栈工具类
 * 
 * @author liu
 * @date 2020-11-02
 */
public class StackTraceUtil {

    /**
     * 获取所有调用了当前方法的方法信息
     */
    public static void getAllInvokMethod() {
        StackTraceElement[] s = new Exception().getStackTrace();
        int i = 2, size = s.length;
        for (; i < size; i++) {
            String className = s[i].getClassName();
            if (className.startsWith("org.springframework.web")) {
                return;
            }
            String getMethodName = s[i].getMethodName();
            int lineNum = s[i].getLineNumber();
            System.out.println("class==" + className + ":method==" + getMethodName + ":行数==" + lineNum);
        }
    }

    /**
     * 获取最近的调用了当前方法的方法信息
     */
    public static void getInvokMethod() {
        getInvokMethod(3);
    }

    /**
     * 获取距离当前方法的第N个调用了当前方法的方法信息
     * 
     * @param n 第几个方法
     */
    public static void getInvokMethod(int n) {
        StackTraceElement[] s = new Exception().getStackTrace();
        String getMethodName = s[n + 1].getMethodName();
        String className = s[n + 1].getClassName();
        int lineNum = s[n + 1].getLineNumber();
        System.out.println("class==" + className + ":method==" + getMethodName + ":行数==" + lineNum);
    }

    /**
     * 获取距离当前方法的第N个调用了当前方法的方法信息
     * 
     * @param n 第几个方法
     */
    public static void getInvokMethod(int... n) {
        StackTraceElement[] s = new Exception().getStackTrace();
        int i = 0, size = n.length;
        for (; i < size; i++) {
            String getMethodName = s[n[i] + 1].getMethodName();
            String className = s[n[i] + 1].getClassName();
            int lineNum = s[n[i] + 1].getLineNumber();
            System.out.println("class==" + className + ":method==" + getMethodName + ":行数==" + lineNum);
        }
    }

    /**
     * 获取距离当前方法的第start个后的size个调用了当前方法的方法信息
     * 
     * @param start 开始方法的数量
     * @param size 查多少个
     */
    public static void getInvokMethod(int start, int size) {
        StackTraceElement[] s = new Exception().getStackTrace();
        start += 1;
        size += start;
        for (; start < size; start++) {
            String getMethodName = s[start].getMethodName();
            String className = s[start].getClassName();
            int lineNum = s[start].getLineNumber();
            System.out.println("class==" + className + ":method==" + getMethodName + ":行数==" + lineNum);
        }
    }

    /**
     * 获取当前类的包的地址
     * 
     * @param obj
     */
    public static void getClassPackage(Class<?> cla) {
        ProtectionDomain pd = cla.getProtectionDomain();

        CodeSource cs = pd.getCodeSource();

        String url = cs.getLocation().toString();
        System.out.println(url.substring(url.indexOf("/") + 1));
    }

}